/*
 * Copyright (C) 2016 volders GmbH with <3 in Berlin
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package berlin.volders.badger;

import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.ColorFilter;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.Rect;
import ohos.agp.utils.TextAlignment;
import ohos.app.Context;

/**
 * Base badge implementation for drawing a colored badge with text on it.#
 * The text is drawn centered on the badge and scaled to fit it.
 * Due to the limited space not all text will fit on it.
 */
public class TextBadge extends BadgeDrawable {

    private static final float MAGIC_TEXT_SCALE_FACTOR = 0.6f;
    public static final float NUM_D5F = 0.5f;


    private final BadgeShape shape;

    private final Paint badgePaint = new Paint();
    private final Paint textPaint = new Paint();
    private boolean paintPreparationNeeded = true;

    private String text = "";

    /**
     * 构造
     *
     * @param context to read themed colors from
     * @param shape   of the badge
     * @see #TextBadge(BadgeShape, int, int)
     */
    public TextBadge(Context context, BadgeShape shape) {
        this(shape, badgeShapeColor(context), badgeTextColor(context));
    }

    /**
     * 构造
     *
     * @param shape      of the badge
     * @param badgeColor to paint the badge shape with
     * @param textColor  to paint the {@code count} with
     */
    protected TextBadge(BadgeShape shape, @ColorInt int badgeColor, @ColorInt int textColor) {
        this.shape = shape;
        badgePaint.setColor(new Color(badgeColor));
        textPaint.setColor(new Color(textColor));
    }

    /**
     * 准备绘制角标
     *
     * @param paint to prepare for drawing the badge
     */
    protected void onPrepareBadgePaint(Paint paint) {
        paint.setAntiAlias(true);
    }

    /**
     * 准备绘制文本
     *
     * @param paint to prepare for drawing the text
     */
    protected void onPrepareTextPaint(Paint paint) {
        paint.setAntiAlias(true);
        paint.setTextAlign(TextAlignment.CENTER);
    }

    /**
     * 绘制
     *
     * @param component
     * @param canvas
     */
    @Override
    public void onDraw(Component component, Canvas canvas) {
        if (text.length() == 0) {
            return;
        }

        if (paintPreparationNeeded) {
            paintPreparationNeeded = false;
            onPrepareBadgePaint(badgePaint);
            onPrepareTextPaint(textPaint);
        }

        Rect rect = shape.draw(component.getContext(), canvas, getBounds(), badgePaint, getLayoutDirection());
        textPaint.setTextSize((int) (rect.getHeight() * MAGIC_TEXT_SCALE_FACTOR));
        float x = rect.getPreciseHorizontalCenter();
        double y = rect.getPreciseVerticalCenter() - (textPaint.ascent() + textPaint.descent()) * NUM_D5F;
        canvas.drawText(textPaint,text, x, (float) y);
    }

    /**
     * 获取布局方向
     *
     * @return int
     */
    public int getLayoutDirection() {
        return 0; // LAYOUT_DIRECTION_LTR

    }

    /**
     * 布局方向改变
     *
     * @param layoutDirection
     * @return boolean
     */
    public boolean onLayoutDirectionChanged(int layoutDirection) {
//        invalidateSelf();
        clearColorMatrix();
        return true;
    }

    /**
     * 设置透明度
     *
     * @param alpha
     */
    @Override
    public void setAlpha(int alpha) {
        if (getAlpha() != alpha) {
            badgePaint.setAlpha(alpha);
            textPaint.setAlpha(alpha);
            super.setAlpha(alpha);
        }
    }

    /**
     * 设置过滤器
     *
     * @param colorFilter
     */
    @Override
    public void setColorFilter(ColorFilter colorFilter) {
        if (getColorFilter() != colorFilter) {
            badgePaint.setColorFilter(colorFilter);
            textPaint.setColorFilter(colorFilter);
            super.setColorFilter(colorFilter);
        }
    }

    /**
     * 设置文本
     *
     * @param text to display in badge
     */
    public final void setText(CharSequence text) {
        String trimmedText = text == null ? "" : text.toString().trim();
        if (!this.text.equals(trimmedText)) {
            this.text = trimmedText;
//            invalidateSelf();
            clearColorMatrix();
        }
    }

    /**
     * 获取文本
     *
     * @return the text
     */
    public final String getText() {
        return text;
    }

    static int badgeShapeColor(Context context) {
        return context.getColor(ResourceTable.Color_badgeShapeColor);
    }

    static int badgeTextColor(Context context) {
        return context.getColor(ResourceTable.Color_badgeTextColor);
    }

    /**
     * {@link BadgeDrawable.Factory} extension for creating {@code TextBadge} instances.
     *
     * @param <T> the subtype of {@code TextBadge} to create
     */
    public static abstract class Factory<T extends TextBadge> implements BadgeDrawable.Factory<T> {

        /**
         * The badge shape
         */
        protected final BadgeShape shape;
        /**
         * The badge color
         */
        @ColorInt
        protected final int badgeColor;
        /**
         * The text color
         */
        @ColorInt
        protected final int textColor;

        /**
         * 工厂构造
         *
         * @param context to read themed colors from
         * @param shape   of the badge
         */
        public Factory(Context context, BadgeShape shape) {
            this(shape, badgeShapeColor(context), badgeTextColor(context));
        }

        /**
         * 工厂构造
         *
         * @param shape      of the badge
         * @param badgeColor to paint the badge shape with
         * @param textColor  to paint the {@code count} with
         */
        public Factory(BadgeShape shape, @ColorInt int badgeColor, @ColorInt int textColor) {
            this.shape = shape;
            this.badgeColor = badgeColor;
            this.textColor = textColor;
        }
    }
}
